<template>
  <div class="row">
    <div class="col-12 text-subtitle1 text-center">登录</div>
    <q-banner inline-actions rounded class="col-12 text-white bg-red q-mt-sm" v-if="serverErrorMessage">
      {{ serverErrorMessage }}
      <template v-slot:action>
        <q-btn flat icon="close" size="sm" dense @click="serverErrorMessage = ''" />
      </template>
    </q-banner>
    <q-input class="col-12 q-mt-md" v-model="form.username" placeholder="用户名" outlined square dense autofocus
      :error="v$.username.$error" :error-message="e$(v$.username.$errors)" no-error-icon :hide-bottom-space="true"
      :disable="workingState" :ref="el => focusHelperLogin.regRef(el, 1)" @keyup.enter="focusHelperLogin.onEntered(1)">
      <template v-slot:append>
        <q-icon name="person" />
      </template>
    </q-input>
    <q-input class="col-12 q-mt-md" v-model="form.password" placeholder="密码" type="password" outlined square dense
      :error="v$.password.$error" :error-message="e$(v$.password.$errors)" no-error-icon :hide-bottom-space="true"
      :disable="workingState" :ref="el => focusHelperLogin.regRef(el, 2)" @keyup.enter="focusHelperLogin.onEntered(2)">
      <template v-slot:append>
        <q-icon name="vpn_key" />
      </template>
    </q-input>
    <q-input class="col-5 q-mt-md" v-model="form.captcha" placeholder="验证码" outlined square dense
      :disable="workingState" :maxlength="4" :error="v$.captcha.$error" :error-message="e$(v$.captcha.$errors)"
      no-error-icon :hide-bottom-space="true" v-if="useLoginCaptcha" :ref="el => focusHelperLogin.regRef(el, 3)"
      @keyup.enter="focusHelperLogin.onEntered(3)"></q-input>
    <div class="col-7 q-mt-md text-right" v-if="useLoginCaptcha" style="height:28px">
      <img :src="captchaUrl" alt="验证码" style="cursor:pointer" title='点击刷新' @click="refreshCaptcha">
    </div>
    <q-btn :loading="workingState" class="q-mt-md col-12" color="primary" label="登录" @click="login">
      <template v-slot:loading>
        <q-spinner class="on-left" />
        登录中...
      </template>
    </q-btn>
  </div>
  <div class="row">
    <slot name="extra-action"></slot>
  </div>
  <div class="row q-mt-md">
    <div class="col-7"><!--占位--></div>
    <div class="row col-5 items-center justify-end">
      <router-link to="/comm/auth/forgot-password">忘记密码</router-link>
    </div>
  </div>
</template>

<script lang="ts">
export default {
  name: 'loginStd',
}
</script>

<script lang="ts" setup>
import { reactive, ref } from 'vue'
import { JsonRespBase, UserAuth, UserRoleRightInfo } from '../../defs/comm'
import useVuelidate from '@vuelidate/core'
import { useFocusNextHelper } from '../../hooks/focusHelper'
import { AxiosResponse } from 'axios'
import { useJsencryptHelper } from '../../hooks/jsencryptHelper'

const captchaUrl = ref(($f.axios.defaults.baseURL ?? '') + '/comm/auth/get-captcha')
const query = $f.router.currentRoute.value.query
const reurl = query.reurl?.toString() ?? '/'

const e$ = $f.getFieldErrStr

//属性
const props = defineProps({
  useLoginCaptcha: {
    type: Boolean,
    default: false,
  }
})

// 0 - 普通登录
const loginType = ref(0)

const encPassword = useJsencryptHelper()

//表单
const form = reactive({
  username: '',
  password: '',
  captcha: '',
})

//表单验证
const rules = {
  username: {
    required: $f.validators.required,
    username: $f.validators.username,
  },
  password: {
    required: $f.validators.required,
    password: $f.validators.password,
  },
  captcha: {
    required: $f.validators.requiredIf(props.useLoginCaptcha),
    length: $f.validators.equalLength(4),
  },
}
const v$ = useVuelidate(rules, form, { $autoDirty: true })

const serverErrorMessage = ref('')
const workingState = ref(false)

const doLogin = function () {
  workingState.value = true
  serverErrorMessage.value = ''
  let workState = 1
  let loginPromise: Promise<AxiosResponse<UserAuth>>
  if ($f.globalCfg.encTransPwd) {
    let encryptedPassword = encPassword(form.password)
    const newForm = {
      username: form.username,
      captcha: form.captcha,
      useEncryptPwd: true,
      encryptedPwd: encryptedPassword,
    }
    loginPromise = $f.axios.post<UserAuth>('comm/auth/login', newForm)
  } else {
    loginPromise = $f.axios.post<UserAuth>('comm/auth/login', form)
  }
  loginPromise
    .then((resp) => {
      if ($f.ua == null) {
        $f.ua = ref(resp.data)
      } else {
        $f.ua.value = resp.data
      }
      localStorage.setItem('ua', JSON.stringify(resp.data))
      workState = 2
      return $f.axios.get<UserRoleRightInfo>('comm/rr/get-my-role-right-info')
    })
    .then((resp) => {
      if ($f.rr == null) {
        $f.rr = ref(resp.data)
      } else {
        $f.rr.value = resp.data
      }
      localStorage.setItem('rr', JSON.stringify(resp.data))
      return $f.router.push(reurl)
    })
    .catch((err) => {
      if (workState === 1 && err?.response?.data) {
        // 特殊处理
        let resp = err?.response?.data as JsonRespBase
        if (err.response.status === 400 && resp.extra) {
          const extra = resp.extra as string
          let extraSegments = extra.split('|')
          if (extraSegments.length === 3) {
            let title = ''
            let type = extraSegments[0]
            if (type === '1') {
              title = '首次登录需要修改密码'
            } else if (type === '2') {
              title = '密码过期需要修改密码'
            }
            if (title) {
              void $f.router
                .push({
                  path: '/comm/auth/reset-password',
                  query: {
                    username: extraSegments[2] ?? form.username,
                    optoken: extraSegments[1],
                    title: title,
                    reurl: reurl,
                    type: type,
                  },
                })
              return
            }
          }
        }
      }
      serverErrorMessage.value = $f.getAxiosErrMsg(err)
      workingState.value = false
      if (loginType.value == 0) {
        refreshCaptcha()
      }
    })
}

const login = function () {
  void v$.value
    .$validate()
    .then((valRes) => {
      if (valRes) {
        doLogin()
      }
    })
}

const refreshCaptcha = function () {
  if (workingState.value) {
    return
  }
  captchaUrl.value = ($f.axios.defaults.baseURL ?? '') + '/comm/auth/get-captcha?' + new Date().getTime().toString()
}

const focusHelperLogin = useFocusNextHelper(login)


</script>
